package com.guoyh.bilbase.base.activity

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.annotation.DrawableRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import com.guoyh.baseutils.entity.LoadStatusEntity
import com.guoyh.baseutils.entity.LoadingDialogEntity
import com.guoyh.baseutils.entity.LoadingType
import com.guoyh.baseutils.ext.toast
import com.guoyh.baseutils.mylog.Loger
import com.guoyh.baseutils.viewModel.SupportViewModel
import com.guoyh.bilbase.R
import com.guoyh.bilbase.base.BaseIView
import com.guoyh.bilbase.enums.PageStateEnum
import com.guoyh.bilbase.ext.*
import com.zy.multistatepage.MultiStateContainer
import com.zy.multistatepage.bindMultiState

/**
 * @CreateDate: 2021/8/18 6:28 下午
 * @Author: guoyh
 * @Description: java类作用描述
 */
abstract class BaseDVActivity<DB : ViewDataBinding, VM : SupportViewModel> : BaseInitActivity(),
    BaseIView {

    //界面状态管理
    protected lateinit var mState: MultiStateContainer

    //当前页面的状态
    var pagetState: PageStateEnum = PageStateEnum.SUCCESS

    lateinit var mDataBind: DB

    //当前Activity绑定的 ViewModel
    lateinit var mViewModel: VM

    //toolbar 这个可替换成自己想要的标题栏
    private var mTitleBarView: View? = null


    /**
     * 创建viewModel
     */
    private fun createViewModel(): VM {
        return ViewModelProvider(this).get(viewModelClass())
    }

    abstract fun viewModelClass(): Class<VM>


    /**
     * 创建DataBind
     */
    private fun createDataBind(): DB {
        val contentView = LayoutInflater.from(this).inflate(layoutId,null)
        val binding = DataBindingUtil.bind<DB>(contentView)!!
        dataBindView = binding.root
        return binding
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_base)
        //生成ViewModel
        if (!this::mViewModel.isInitialized) {
            mViewModel = createViewModel()
        }
        if (!this::mDataBind.isInitialized) {
            mDataBind = createDataBind()
        }

        //初始化 status View
        initStatusView(savedInstanceState)
        //注册界面响应事件
        initLoadingUiChange()
        //初始化绑定observer
        initObserver()
        initData()
        //初始化绑定点击方法
        onBindViewClick()
    }

    val rootView by lazy {
        findViewById<LinearLayout>(R.id.baseRootView)
    }

    val baseContentView by lazy {
        findViewById<FrameLayout>(R.id.baseContentView)
    }


    private fun initStatusView(savedInstanceState: Bundle?) {
        mTitleBarView = getTitleBarView()

        mTitleBarView?.let {
            (it.parent as ViewGroup)?.removeView(it)
            rootView.addView(it, 0)
        }
        baseContentView.addView(dataBindView)
        val loadingView =
            if (getLoadingView() == null) baseContentView else getLoadingView()!!

        mState = loadingView.bindMultiState {
            onLoadRetry()
        }

        baseContentView.post {
            initView(savedInstanceState)
        }
    }

    /**
     * 初始化view
     */
    abstract fun initView(savedInstanceState: Bundle?)

    /**
     * 创建观察者
     */
    open fun initObserver() {}

    /**
     * 获取数据
     */
    open fun initData() {}


    /**
     * 点击事件方法 配合setOnclick()拓展函数调用，做到黄油刀类似的点击事件
     */
    open fun onBindViewClick() {}

    /**
     * 注册 UI 事件 监听请求时的回调UI的操作
     */
    private fun initLoadingUiChange() {
        mViewModel.loadingChange.run {


            loading.observeInActivity(this@BaseDVActivity) {

                if (it.loadingType == LoadingType.LOADING_DIALOG) {
                    if (it.isShow) {
                        showLoading(it)
                    } else {
                        dismissLoading(it)
                    }
                    return@observeInActivity
                }
                if (it.loadingType == LoadingType.LOADING_CUSTOM) {
                    if (it.isShow) {
                        showCustomLoading(it)
                    } else {
                        dismissCustomLoading(it)
                    }
                    return@observeInActivity
                }
                if (it.loadingType == LoadingType.LOADING_XML) {
                    if (it.isShow) {
                        showLoadingUi()
                    }
                    return@observeInActivity
                }
            }

            showEmpty.observeInActivity(this@BaseDVActivity) {
                onRequestEmpty(it)
            }
            showError.observeInActivity(this@BaseDVActivity) {
                //如果请求错误 并且loading类型为 xml 那么控制界面显示为错误布局
                if (it.loadingType == LoadingType.LOADING_XML) {
                    showErrorUi(it.errorMessage)
                }
                onRequestError(it)
            }
            showSuccess.observeInActivity(this@BaseDVActivity) {
                showSuccessUi()
            }
        }
    }

    /**
     * 请求列表数据为空时 回调
     * @param loadStatus LoadStatusEntity
     */
    override fun onRequestEmpty(loadStatus: LoadStatusEntity) {
        showEmptyUi()
    }

    /**
     * 请求接口失败回调，如果界面有请求接口，需要处理错误业务，请实现它 如果不实现那么 默认吐司错误消息
     * @param loadStatus LoadStatusEntity
     */
    override fun onRequestError(loadStatus: LoadStatusEntity) {
        loadStatus.errorMessage.toast()
    }

    /**
     * 空界面，错误界面 点击重试时触发的方法，如果有使用 状态布局的话，一般子类都要实现
     */
    override fun onLoadRetry() {}

    /**
     * 显示 成功状态界面
     */
    override fun showSuccessUi() {
        if (this::mState.isInitialized && pagetState != PageStateEnum.SUCCESS) {
            pagetState = PageStateEnum.SUCCESS
            mState.showSuccess()
        }
    }

    /**
     * 显示 错误 状态界面
     * @param errMessage String
     */
    override fun showErrorUi(msg: String, @DrawableRes drawableRes: Int) {
        if (this::mState.isInitialized && pagetState != PageStateEnum.ERROR) {
            pagetState = PageStateEnum.ERROR
            mState.showError(msg, drawableRes)
        }

    }

    /**
     * 显示 错误 状态界面
     */
    override fun showEmptyUi(msg: String, @DrawableRes drawableRes: Int) {
        if (this::mState.isInitialized && pagetState != PageStateEnum.EMPTY) {
            pagetState = PageStateEnum.EMPTY
            mState.showEmpty(msg, drawableRes)
        } else {
            Loger.dd("Kong1111")

        }
    }

    /**
     * 显示 loading 状态界面
     */

    override fun showLoadingUi(msg: String) {
        if (this::mState.isInitialized && pagetState != PageStateEnum.LOADING) {
            pagetState = PageStateEnum.LOADING
            mState.showLoading(msg)
        }
    }


    /**
     * 显示自定义loading 在请求时 设置 loadingType类型为LOADING_CUSTOM 时才有效 可以根据setting中的requestCode判断
     * 具体是哪个请求显示该请求自定义的loading
     * @param setting LoadingDialogEntity
     */
    override fun showCustomLoading(setting: LoadingDialogEntity) {
        showLoadingExt()
    }

    /**
     * 隐藏自定义loading 在请求时 设置 loadingType类型为LOADING_CUSTOM 时才有效 可以根据setting中的requestCode判断
     * 具体是哪个请求隐藏该请求自定义的loading
     * @param setting LoadingDialogEntity
     */
    override fun dismissCustomLoading(setting: LoadingDialogEntity) {
        dismissLoadingExt()
    }

    override fun showLoading(setting: LoadingDialogEntity) {
        showLoadingExt()
    }

    override fun dismissLoading(setting: LoadingDialogEntity) {
        dismissLoadingExt()
    }
}